package com.study.framework.pic;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class ImageWatermarkProcessor {

    // 支持的图片格式
    private static final List<String> SUPPORTED_FORMATS = Arrays.asList(
            "jpg", "jpeg", "png", "bmp", "gif", "tiff", "webp"
    );

    // 支持的中文字体列表
    private static final String[] CHINESE_FONTS = {
            "微软雅黑", "Microsoft YaHei", "SimHei", "黑体", "宋体", "SimSun",
            "Arial Unicode MS", "PingFang SC", "Helvetica Neue", "Helvetica"
    };

    public static void main(String[] args) {
        // 示例使用
        String sourceFolder = "D:\\我的文档\\我的\\郭南琛\\打印照片"; // 源文件夹路径
        String targetFolder = "D:\\我的文档\\我的\\郭南琛\\打印照片水印"; // 目标文件夹路径

        try {
            processImagesWithWatermark(sourceFolder, targetFolder);
            System.out.println("图片水印添加完成！");
        } catch (Exception e) {
            System.err.println("处理过程中出现错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 批量处理文件夹中的图片并添加水印（分离存储）
     * @param sourceFolder 源文件夹路径
     * @param targetFolder 目标文件夹路径
     */
    public static void processImagesWithWatermark(String sourceFolder, String targetFolder) throws IOException {
        File sourceDir = new File(sourceFolder);
        File targetDir = new File(targetFolder);

        if (!sourceDir.exists() || !sourceDir.isDirectory()) {
            throw new IllegalArgumentException("源文件夹不存在或不是文件夹: " + sourceFolder);
        }

        // 创建目标文件夹（如果不存在）
        if (!targetDir.exists()) {
            if (!targetDir.mkdirs()) {
                throw new IOException("无法创建目标文件夹: " + targetFolder);
            }
        }

        processFolderRecursively(sourceDir, targetDir);
    }

    /**
     * 递归处理文件夹
     * @param sourceFolder 源文件夹
     * @param targetFolder 目标文件夹
     */
    private static void processFolderRecursively(File sourceFolder, File targetFolder) throws IOException {
        File[] files = sourceFolder.listFiles();
        if (files == null) return;

        for (File file : files) {
            if (file.isDirectory()) {
                // 计算对应的子文件夹路径
                String relativePath = getRelativePath(file, sourceFolder);
                File targetSubFolder = new File(targetFolder, relativePath);

                // 创建目标子文件夹
                if (!targetSubFolder.exists()) {
                    if (!targetSubFolder.mkdirs()) {
                        System.err.println("无法创建子文件夹: " + targetSubFolder.getAbsolutePath());
                        continue;
                    }
                }

                // 递归处理子文件夹
                processFolderRecursively(file, targetSubFolder);
            } else if (isImageFile(file)) {
                // 计算目标文件路径
                String relativePath = getRelativePath(file, sourceFolder);
                File targetFile = new File(targetFolder, relativePath);

                // 处理图片文件并保存到目标位置
                addWatermarkToImage(file, targetFile, sourceFolder.getName());
            }
        }
    }

    /**
     * 获取文件相对于源文件夹的相对路径
     * @param file 文件
     * @param sourceFolder 源文件夹
     * @return 相对路径
     */
    private static String getRelativePath(File file, File sourceFolder) {
        String sourcePath = sourceFolder.getAbsolutePath();
        String filePath = file.getAbsolutePath();

        if (filePath.startsWith(sourcePath)) {
            String relativePath = filePath.substring(sourcePath.length());
            // 移除开头的路径分隔符
            if (relativePath.startsWith(File.separator)) {
                relativePath = relativePath.substring(1);
            }
            return relativePath;
        }

        return file.getName();
    }

    /**
     * 判断是否为图片文件
     * @param file 文件
     * @return 是否为图片文件
     */
    private static boolean isImageFile(File file) {
        String fileName = file.getName().toLowerCase();
        String extension = getFileExtension(fileName);
        return SUPPORTED_FORMATS.contains(extension);
    }

    /**
     * 获取文件扩展名
     * @param fileName 文件名
     * @return 文件扩展名
     */
    private static String getFileExtension(String fileName) {
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
            return fileName.substring(lastDotIndex + 1);
        }
        return "";
    }

    /**
     * 给图片添加水印并保存到指定位置
     * @param sourceImageFile 源图片文件
     * @param targetImageFile 目标图片文件
     * @param watermarkText 水印文字（文件夹名称）
     */
    private static void addWatermarkToImage(File sourceImageFile, File targetImageFile, String watermarkText) throws IOException {
        System.out.println("正在处理图片: " + sourceImageFile.getAbsolutePath());

        // 读取原图片
        BufferedImage originalImage = ImageIO.read(sourceImageFile);
        if (originalImage == null) {
            System.err.println("无法读取图片: " + sourceImageFile.getAbsolutePath());
            return;
        }

        // 创建带水印的图片
        BufferedImage watermarkedImage = addWatermark(originalImage, watermarkText);

        // 确保目标文件的父目录存在
        File targetParentDir = targetImageFile.getParentFile();
        if (targetParentDir != null && !targetParentDir.exists()) {
            if (!targetParentDir.mkdirs()) {
                System.err.println("无法创建目标文件夹: " + targetParentDir.getAbsolutePath());
                return;
            }
        }

        // 保存图片到目标位置
        String formatName = getImageFormat(sourceImageFile);
        ImageIO.write(watermarkedImage, formatName, targetImageFile);

        System.out.println("水印添加完成: " + targetImageFile.getAbsolutePath());
    }

    /**
     * 在图片上添加水印（只在右下角）
     * @param originalImage 原图片
     * @param watermarkText 水印文字
     * @return 添加水印后的图片
     */
    private static BufferedImage addWatermark(BufferedImage originalImage, String watermarkText) {
        int width = originalImage.getWidth();
        int height = originalImage.getHeight();

        // 创建新的图片对象
        BufferedImage watermarkedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = watermarkedImage.createGraphics();

        // 绘制原图片
        g2d.drawImage(originalImage, 0, 0, null);

        // 设置水印样式（包含中文字体支持）
        setupWatermarkStyle(g2d, width, height);

        // 计算水印位置和大小
        FontMetrics fontMetrics = g2d.getFontMetrics();
        int textWidth = fontMetrics.stringWidth(watermarkText);
        int textHeight = fontMetrics.getHeight();

        // 只在右下角添加水印
        int x = width - textWidth - 20; // 距离右边20像素
        int y = height - 20; // 距离底部20像素

        // 确保水印不会超出图片边界
        if (x < 10) x = 10;
        if (y < textHeight) y = textHeight;

        // 绘制水印文字边框（增强可读性）
        g2d.setColor(Color.BLACK);
        g2d.drawString(watermarkText, x + 1, y + 1);
        g2d.drawString(watermarkText, x - 1, y - 1);
        g2d.drawString(watermarkText, x + 1, y - 1);
        g2d.drawString(watermarkText, x - 1, y + 1);

        // 绘制主要水印文字
        g2d.setColor(Color.WHITE);
        g2d.drawString(watermarkText, x, y);

        g2d.dispose();
        return watermarkedImage;
    }

    /**
     * 设置水印样式（解决中文乱码问题）
     * @param g2d Graphics2D对象
     * @param width 图片宽度
     * @param height 图片高度
     */
    private static void setupWatermarkStyle(Graphics2D g2d, int width, int height) {
        // 获取支持中文的字体
        Font chineseFont = getAvailableChineseFont();

        // 设置字体大小
        int fontSize = Math.max(12, Math.min(width / 25, 36));
        Font font = chineseFont.deriveFont(Font.BOLD, (float) fontSize);
        g2d.setFont(font);

        // 设置抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        // 设置渲染质量
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

        // 设置透明度
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
    }

    /**
     * 获取系统中可用的中文字体
     * @return 支持中文的字体
     */
    private static Font getAvailableChineseFont() {
        // 获取系统所有可用字体
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] availableFontFamilyNames = ge.getAvailableFontFamilyNames();

        // 检查是否有支持中文的字体
        for (String fontName : CHINESE_FONTS) {
            for (String availableFont : availableFontFamilyNames) {
                if (availableFont.equalsIgnoreCase(fontName)) {
                    try {
                        Font font = new Font(fontName, Font.BOLD, 12);
                        // 测试字体是否能正确显示中文
                        if (canDisplayChinese(font)) {
                            System.out.println("使用字体: " + fontName);
                            return font;
                        }
                    } catch (Exception e) {
                        // 字体不可用，继续尝试下一个
                    }
                }
            }
        }

        // 如果没有找到合适的中文字体，使用系统默认字体并尝试设置
        Font defaultFont = new Font("Dialog", Font.BOLD, 12);
        if (canDisplayChinese(defaultFont)) {
            System.out.println("使用系统默认字体");
            return defaultFont;
        }

        // 最后的备选方案
        System.out.println("使用备选字体方案");
        return new Font("SansSerif", Font.BOLD, 12);
    }

    /**
     * 检查字体是否能显示中文字符
     * @param font 要检查的字体
     * @return 是否能显示中文
     */
    private static boolean canDisplayChinese(Font font) {
        String testChinese = "测试中文水印";
        return font.canDisplayUpTo(testChinese) == -1;
    }

    /**
     * 获取图片格式
     * @param imageFile 图片文件
     * @return 图片格式
     */
    private static String getImageFormat(File imageFile) {
        String fileName = imageFile.getName().toLowerCase();
        String extension = getFileExtension(fileName);

        // 标准化格式名称
        switch (extension) {
            case "jpg":
            case "jpeg":
                return "JPEG";
            case "png":
                return "PNG";
            case "gif":
                return "GIF";
            case "bmp":
                return "BMP";
            default:
                return "JPEG"; // 默认使用JPEG格式
        }
    }
}
